import { Tool, ToolColor } from '../../../Tool';

var AnglePolyLinePrimitive = (function () {
	function _(positions, dataSource) {
		this.options = {
			name: 'fe-angle',
			polyline: {
				show: true,
				positions: [],
				material: Cesium.Color.fromCssColorString(ToolColor.functionalColor),
				depthFailMaterial: Cesium.Color.fromCssColorString(ToolColor.functionalColor),
				width: 2
			}
		};
		this.dataSource = dataSource;
		this.positions = positions;
		this.entity = this._init();
	}

	_.prototype._init = function () {
		const _update = () => this.positions;
		// 实时更新polyline.positions

		this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
		return this.dataSource.entities.add(this.options);
	};

	return _;
})();

/**
 * 角度测量
 */
export class AngleTool extends Tool {
	constructor(viewer, options = {}, ...args) {
		super(arguments);
		this.viewer = viewer;
		this.options = options;
		this.float = options?.float ?? 2;

		this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
		this.dataSource = new Cesium.CustomDataSource('fe-angle');
		this.viewer.dataSources.add(this.dataSource);
		viewer.scene.layers.layerQueue.forEach((item) => {
			item.selectEnabled = false;
			item.releaseSelection();
		});
		[...arguments].forEach((item) => {
			if (typeof item === 'function') {
				this.callback = item;
			}
		});
		this.callbackValue = {
			total: null,
			current: null,
			tool: this
		};
	}

	start() {
		let count = 0;
		let poly = null;
		let angle = 0;
		let positions = [];
		let startFlag = false;

		this.handler.setInputAction((e) => {
			if (startFlag) {
				count++;
				if (count > 3) return;
				if (count === 3) {
					this.dataSource.entities.add({
						polyline: {
							positions: positions,
							material: Cesium.Color.fromCssColorString(ToolColor.functionalColor),
							depthFailMaterial: Cesium.Color.fromCssColorString(ToolColor.functionalColor),
							width: 2
						}
					});
					this.dataSource.entities.remove(this.handler.poly);
					startFlag = false;

					this.callbackValue.current = angle.toFixed(this.float) + '°';
					this.callback && this.callback(this.callbackValue);
				}
				const cartesian = this.viewer.scene.pickPosition(e.position);
				if (positions.length === 0) {
					positions.push(cartesian.clone());
				}
				positions.push(cartesian);
				if (count === 2) {
					this.dataSource.entities.add({
						name: 'fe-angle-text',
						position: cartesian,
						label: {
							text: new Cesium.CallbackProperty(() => {
								return angle.toFixed(this.float) + '°';
							}, false),
							font: '14px sans-serif',
							showBackground: true,
							backgroundColor: Cesium.Color.fromCssColorString(
								ToolColor.toRgba(ToolColor.backgroundColor, 0.8)
							),
							fillColor: Cesium.Color.fromCssColorString(ToolColor.color),
							disableDepthTestDistance: Number.POSITIVE_INFINITY,
							verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
							pixelOffset: new Cesium.Cartesian2(0, 20)
						}
					});
				}
			}
		}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

		this.handler.setInputAction((movement) => {
			if (!startFlag || count > 3) return;
			const cartesian = this.viewer.scene.pickPosition(movement.endPosition);
			if (positions.length >= 2) {
				if (!Cesium.defined(poly)) {
					poly = new AnglePolyLinePrimitive(positions, this.dataSource);
					this.handler.poly = poly.entity;
				} else {
					positions.pop();
					positions.push(cartesian);
				}
				if (positions.length === 3) {
					const edge1 = {};
					const edge2 = {};
					Cesium.Cartesian3.subtract(positions[1], positions[0], edge1);
					Cesium.Cartesian3.subtract(positions[1], cartesian, edge2);
					const angleRadian = Cesium.Cartesian3.angleBetween(edge1, edge2);
					angle = Cesium.Math.toDegrees(angleRadian);
				}
			}
		}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

		angle = 0;
		count = 0;
		positions = [];
		startFlag = true;
	}

	cancel() {
		this.handler.destroy();
		this.dataSource.entities.removeAll();
		this.viewer.dataSources.remove(this.dataSource);
		return super.cancel();
	}
}
AngleTool.toolId = 'AngleTool';
